<template>
  <div
    ref="playWnd"
    :id="id"
    style="display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; font-size: 18px"
  ></div>
</template>

<script>
export default {
  name: 'HKWebPluginPlayer',
  props: {
    appKey: { type: String, default: '24024771' },
    secretKey: { type: String, default: '0K2Zwzcsev8rul0XkDeE' },
    ip: { type: String, default: '183.223.249.216' },
    port: { type: [String, Number], default: 82 },
    toolBar: { type: [Boolean], default: true },
    cameraCode: { type: String, default: '' },
    /* 开始时间戳，单位 秒 */
    startTime: { type: [String, Number], default: '' },
    /* 结束时间戳，单位 秒 */
    endTime: { type: [String, Number], default: '' },
    /* 初始播放模式 */
    isPlayback: { type: Boolean, default: false },
    pluginDownloadUrl: { type: String, default: 'https://m.xinwangzn.com:8081/download/HKVideoWebPlugin.exe' },
    /* 初始播放窗口布局 */
    // layout: {
    //   type: String,
    //   default: layout[0],
    //   validator(v) {
    //     return layout.indexOf(v) >= 0;
    //   },
    // },
  },
  data() {
    return {
      id: 'HKWebPluginPlayer-' + Date.now(),
      initCount: 0,
    };
  },
  computed: {
    playOption() {
      return {
        cameraIndexCode: this.cameraCode,
        startTimeStamp: this.startTime,
        endTimeStamp: this.endTime,
      };
    },
  },
  mounted() {
    this.playerSize = {
      width: this.$refs.playWnd.clientWidth,
      height: this.$refs.playWnd.clientHeight,
    };
    console.log('mounted');
    this.initPlugin().then(() => {
      const handlePlayOptionChange = this.isPlayback === true ? this.startPlayback : this.startPreview;
      this.$watch(() => this.playOption, handlePlayOptionChange, {
        immediate: true,
        deep: true,
      });
    });
  },
  unmounted() {
    this.destroy();
  },
  methods: {
    initPlugin() {
      return new Promise((resolve) => {
        console.log('initPlugin start');
        this.oWebControl = new WebControl({
          szPluginContainer: this.id, //指定容器id
          iServicePortStart: 15900, //指定起止端口号，建议使用该值
          iServicePortEnd: 15909,
          cbConnectSuccess: async () => {
            console.log('cbConnectSuccess');
            const { width, height } = this.playerSize;
            // setCallbacks();
            //实例创建成功后需要启动服务
            await this.oWebControl.JS_StartService('window', {
              dllPath: './VideoPluginConnect.dll',
            });
            this.oWebControl.JS_SetWindowControlCallback({
              // 设置消息回调
              cbIntegrationCallBack: this.cbIntegrationCallBack,
            });
            await this.oWebControl.JS_CreateWnd(this.id, width, height);
            //JS_CreateWnd创建视频播放窗口，宽高可设定
            await this.initWebControl(); //创建播放实例成功后初始化
            this.initCount = 0;
            resolve();
          },
          cbConnectError: async () => {
            console.log('cbConnectError');
            this.writeMsg("<span style='color: #fff'>插件未启动，正在尝试启动，请稍候...</span>");
            await WebControl.JS_WakeUp('VideoWebPlugin://'); //程序未启动时执行error函数，采用wakeup来启动程序
            if (this.initCount++ < 3) {
              setTimeout(this.initPlugin, 3000);
            } else {
              console.log('add close web plugin eventListener');
              window.addEventListener('click', this.closePlayer);
              this.writeMsg(
                `<span style='color: #f00'>插件启动失败，请先安装插件！<br/><a href='${this.pluginDownloadUrl}' id='download-plugin'>点击下载插件</a></span>`
              );
            }
          },
          cbConnectClose: () => {
            console.log('cbConnectClose');
            this.initCount = 0;
          },
        });
        console.log('initPlugin end');
      });
    },
    async initWebControl() {
      const pubKey = await this.getPubKey();
      console.log('initWebControl', this.ip, this.port, this.appKey, pubKey, this.secretKey);
      // debugger;
      ////////////////////////////////// 请自行修改以上变量值	////////////////////////////////////
      await this.oWebControl.JS_RequestInterface({
        funcName: 'init',
        argument: JSON.stringify({
          appkey: this.appKey, //API网关提供的appkey
          secret: this.getEncryptSecret(pubKey), //API网关提供的secret
          ip: this.ip, //API网关IP地址
          port: Number(this.port), //端口
          playMode: this.isPlayback === true ? 1 : 0, //初始播放模式：0-预览，1-回放
          snapDir: 'D:\\SnapDir', //抓图存储路径
          videoDir: 'D:\\VideoDir', //紧急录像或录像剪辑存储路径
          layout: '1x1', //布局
          enableHTTPS: 1, //是否启用HTTPS协议
          encryptedFields: 'secret', //加密字段
          showToolbar: 1, //是否显示工具栏
          showSmart: 1, //是否显示智能信息
          buttonIDs: this.getToolBar(), //自定义工具条按钮
          // reconnectTimes: 3, //重连次数
          // reconnectDuration: 3000, //重连间隔
        }),
      });
      const { width, height } = this.playerSize;
      this.oWebControl.JS_Resize(width, height); // 初始化后resize一次，规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
      this.addEvent();
      console.log(this.oWebControl);
    },
    cbIntegrationCallBack(oData) {
      const res = oData ? oData.responseMsg || {} : {};
      const { type, msg = {} } = res;
      console.log(oData, res, type, msg);
      this.handleWebControlMsg(type, msg);
    },
    handleWebControlMsg(type, msg) {
      const _this = this;
      const handler = {
        1: function onWinSelect(msg) {
          return {
            256: function onPlaying({ cameraIndexCode }) {
              _this.$emit('select', cameraIndexCode);
            },
            512: function onFreeWin() {},
          }[msg.result];
        },
        2: function onWinPlay(msg) {
          return {
            768: function onPlayStart() {},
            769: function onNetError({ cameraIndexCode }) {
              _this.$emit('close', cameraIndexCode);
            },
            770: function onPlayError({ cameraIndexCode }) {
              _this.$emit('close', cameraIndexCode);
            },
            816: function onPlayEnd({ cameraIndexCode }) {
              _this.$emit('close', cameraIndexCode);
            },
          }[msg.result];
        },
        3: function onScreenshots() {},
        4: function onVideoRecorder() {},
        5: function onFullscreen() {},
      };
      if (handler[type]) {
        const handle = handler[type](msg);
        if (typeof handle === 'function') {
          handle(msg);
        }
      }
    },
    addEvent() {
      if (this.eventListened) return;
      window.removeEventListener('resize', this.onWinResize);
      window.removeEventListener('scroll', this.onWinResize);
      this.eventListened = true;
    },
    removeEvent() {
      window.removeEventListener('resize', this.onWinResize);
      window.removeEventListener('scroll', this.onWinResize);
      this.eventListened = false;
    },
    onWinResize() {
      if (!this.oWebControl) return;
      const { width, height } = this.playerSize;
      this.oWebControl.JS_Resize(width, height);
    },
    getToolBar() {
      return this.toolBar ? '0, 16, 256, 257, 258, 259, 260, 512, 513, 514, 515, 516, 517, 768, 769' : '';
    },
    // 获取公钥
    async getPubKey() {
      let pubKey = '';
      const oData = await this.oWebControl.JS_RequestInterface({
        funcName: 'getRSAPubKey',
        argument: JSON.stringify({
          keyLength: 1024,
        }),
      });
      // console.log(oData);
      if (oData && oData.responseMsg && oData.responseMsg.data) {
        pubKey = oData.responseMsg.data;
      }
      return pubKey;
    },
    // RSA加密
    getEncryptSecret(pubKey) {
      const encrypt = new JSEncrypt();
      encrypt.setPublicKey(pubKey);
      return encrypt.encrypt(this.secretKey);
    },
    writeMsg(msg = '') {
      if (this.$refs.playWnd) this.$refs.playWnd.innerHTML = msg;
    },
    startPreview({ cameraIndexCode }) {
      // debugger;
      if (!cameraIndexCode) {
        console.error('cameraIndexCode is not valid');
        return;
      }
      this.oWebControl.JS_RequestInterface({
        funcName: 'startPreview',
        argument: JSON.stringify({
          cameraIndexCode: cameraIndexCode, //监控点编号
          streamMode: 1, ////主子码流标识：0-主码流，1-子码流
          transMode: 1, //传输协议：0-UDP，1-TCP
          gpuMode: 0, //是否启用GPU硬解，0-不启用，1-启用
          wndId: -1, //播放窗口序号（在2x2以上布局下可指定播放窗口）
        }),
      });
    },
    /*录像回放功能*/
    startPlayback({ cameraIndexCode, startTimeStamp, endTimeStamp }) {
      if (!cameraIndexCode) {
        console.error('cameraIndexCode is not valid');
        return;
      }
      const recordLocation = 1; //录像存储位置：0-中心存储，1-设备存储
      const transMode = 1; //传输协议：0-UDP，1-TCP
      const gpuMode = 0; //是否启用GPU硬解，0-不启用，1-启用
      const wndId = -1; //播放窗口序号（在2x2以上布局下可指定播放窗口）
      this.oWebControl.JS_RequestInterface({
        funcName: 'startPlayback',
        argument: JSON.stringify({
          cameraIndexCode: cameraIndexCode, //监控点编号
          startTimeStamp: startTimeStamp, //录像查询开始时间戳，单位：秒
          endTimeStamp: endTimeStamp, //录像结束开始时间戳，单位：秒
          recordLocation: recordLocation, //录像存储类型：0-中心存储，1-设备存储
          transMode: transMode, //传输协议：0-UDP，1-TCP
          gpuMode: gpuMode, //是否启用GPU硬解，0-不启用，1-启用
          wndId: wndId, //可指定播放窗口
        }),
      });
    },
    /*停止回放*/
    stopAllPlayback() {
      if (!this.oWebControl) return;
      try {
        this.oWebControl.JS_RequestInterface({
          funcName: 'stopAllPlayback',
        });
      } catch (e) {
        console.error(e);
      }
    },
    destroy() {
      this.initCount = 0;
      if (this.oWebControl) {
        this.removeEvent();
        this.stopAllPlayback();
        this.oWebControl.JS_HideWnd();
        this.oWebControl.JS_Disconnect();
      }
    },
    closePlayer(e) {
      if (e.target.id === 'download-plugin') {
        window.removeEventListener('click', this.closePlayer);
        this.destroy();
        this.$emit('closePlayer');
      }
    },
  },
};
</script>
